/*
 *  main.c
 *  halo3timer
 *
 *  Created by Phillip LeBlanc on 10/22/08.
 *  Copyright 2008 Team FEV. All rights reserved.
 *
 */

#include "common.h"


#include <sys/timeb.h>

void formatTime(char *ch, int tim);

int get_sec()
{
	struct timeb timebuffer;
	ftime(&timebuffer);
	return (timebuffer.time);
}

SDL_Surface *bg;
SDL_Rect bgdest;
SDL_Surface *notification_bg;
SDL_Rect ndest;
char fullpath[100];

int snipertime, rocketstime, camotime, overtime, hilltime;
int l_time;

map *loadmap;

int main(int argc, char *argv[])
{		
		SDL_Setup();
		
		SDL_Event event;
		int done = 0;
		map themap;
		int maptype, gametype;
    
    while((!done) && (SDL_WaitEvent(&event))) {
        switch(event.type) {
            case SDL_KEYDOWN:
				if (event.key.keysym.sym == SDLK_ESCAPE) {
					Mix_CloseAudio();
					TTF_CloseFont(font);
					SDL_Quit();
					exit(0);} 
				break;
					

            case SDL_MOUSEBUTTONDOWN:
                // Handle mouse clicks here.
				maptype = checkCoords(event.button.x, event.button.y, MAPS);
				if (maptype!=-1) { //Check to see if they clicked a valid map
					gametype = select_gametype();
					if(gametype!=-1) { //They picked a gametype
					  if (strcmp("undefined.txt", mapname[maptype][gametype]) != 0) {
						loadMap(&themap, addpath(mapname[maptype][gametype])); //Load map settings
						fprintf(stderr, "Loaded map %s\n", mapname[maptype][gametype]);
						if (event_loop_start()!= -1)
							start_timer(&themap); //start the timer
					   } //end strcmp if
					   else
							event_loop_undef();
					} //end gametype if
					setBG(addpath("images/maps.jpg"));
					break;
					} //end if
				break;

            case SDL_QUIT:
                Mix_CloseAudio();
				TTF_CloseFont(font);
				SDL_Quit();
				exit(0);
                
            default:
                break;
        }   // End switch
            
    }   // End while
	
		Mix_CloseAudio();
		TTF_CloseFont(font);
		SDL_Quit();
        return 0;

}

int g_time(int e_time)  //Return how many seconds are left in the game, cannot be called before e_time is set
{
	return e_time-get_sec();
}

int start_timer(map *themap)
{
		loadmap=themap;
		//fprintf(stderr, "Game Time: %d\n", themap->gtime);
		int s_time = get_sec(); //start time
		int e_time = s_time + themap->gtime; //end time = start time + game time
		int running = 1; //Used for event loop. 1 if it should run, 0 if not

		SDL_Event event;
		
		/*all of the individual timers*/

		snipertime = themap->sniper;
		rocketstime = themap->rockets;
		camotime = themap->camo;
		overtime = themap->over;
		hilltime = themap->gtype.hill.hillmove;
		initTimers();
		
		
		setBG(addpath("images/clock.jpg"));
        while(running==1)
        {
				l_time = g_time(e_time); //Time in this loop
				if (l_time <= 0) {
					running=0; break;}
					
				redrawScreen();
			
				int area;
				
				/*********************Individual Timers**********************/
				char timer[50];
				formatTime(timer, l_time);
				showTime(timer, GAME);
				
				snipertime = updateSniper(themap, snipertime);
				formatTime(timer, snipertime);
				showTime(timer, SNIPER);
				
				rocketstime = updateRockets(themap, rocketstime);
				formatTime(timer, rocketstime);
				showTime(timer, ROCKETS);
				
				camotime = updateCamo(themap, camotime);
				formatTime(timer, camotime);
				showTime(timer, CAMO);
				
				overtime = updateOver(themap, overtime);
				formatTime(timer, overtime);
				showTime(timer, OVER);
				
				hilltime = updateHill(themap, hilltime);
				formatTime(timer, hilltime);
				showTime(timer, HILL);
				
				
				SDL_Flip(screen);	//And finally, display the screen;
				
								
				while (g_time(e_time) == l_time) {     //Check to see if the game time has increased by one second, if not wait
					SDL_PollEvent(&event);			   //If user tries to exit program, let it die
					switch(event.type){
						case SDL_MOUSEBUTTONDOWN:
							area = check_area(event.button.x, event.button.y);
							switch (area){
								case PAUSE_PLAY:
									pause_timer(&e_time);
									setBG(addpath("images/clock.JPG"));
									displayTimers();
									while (1) {
										SDL_PollEvent(&event);
										if (event.type == SDL_MOUSEBUTTONDOWN)
											continue;
										break;
									}
										
									break;
								case RESET:
									snipertime = themap->sniper;
									rocketstime = themap->rockets;
									camotime = themap->camo;
									overtime = themap->over;
									hilltime = themap->gtype.hill.hillmove;
									initTimers();
									s_time = get_sec(); //start time
									e_time = s_time + themap->gtime; //end time = start time + game time
									displayNotification("Reset Timers", 3);
									break;
								default:
									break;
							}
							
							
							break;
						case SDL_KEYDOWN:
							if (event.key.keysym.sym==SDLK_ESCAPE) {
								clearNotification();
								return 1;
							}
							if (event.key.keysym.sym==SDLK_q) {
								clearNotification();
								setBG(addpath("images/clock.JPG"));
								displayTimers();
								break;
							}
							if (event.key.keysym.sym==SDLK_SPACE) {
								pause_timer(&e_time);
								setBG(addpath("images/clock.JPG"));
								displayTimers();
								while (1) {
									SDL_PollEvent(&event);
									if (event.type == SDL_KEYDOWN)
										continue;
									break;
								}
								break;
							}
							if (event.key.keysym.sym==SDLK_LSHIFT) {
								displayNotification("Sniper Glitch Fix Activated", 10);
								snipertime += 41;
								while(1) {
									SDL_PollEvent(&event);
									if ((event.key.keysym.sym==SDLK_LSHIFT)&&(event.type==SDL_KEYDOWN))
										continue;
									break;} //end while(1)
								break;} //end if (event.key.keysym==SDLK_LSHIFT)
							if (event.key.keysym.sym==SDLK_RSHIFT) {
								displayNotification("Rockets Glitch Fix Activated", 10);
								rocketstime += 41;
								while(1) {
									SDL_PollEvent(&event);
									if ((event.key.keysym.sym==SDLK_RSHIFT)&&(event.type==SDL_KEYDOWN))
										continue;
									break;} //end while(1)
								break;} //end if (event.key.keysym==SDLK_RSHIFT)
							if (event.key.keysym.sym==SDLK_r) {	//User reset the timer
								snipertime = themap->sniper;
								rocketstime = themap->rockets;
								camotime = themap->camo;
								overtime = themap->over;
								hilltime = themap->gtype.hill.hillmove;
								initTimers();
								s_time = get_sec(); //start time
								e_time = s_time + themap->gtime; //end time = start time + game time
								displayNotification("Reset Timers", 3);
								break;
							}
								
							if (leftsidekeyboard(event.key.keysym.sym)) {
								displayNotification("Reset Power Up", 7);
								if (themap->camo <= 0)
									overtime = themap->over;
								camotime = themap->camo;}
							else {
								displayNotification("Reset Power Up", 7);
								if (themap->over <= 0)
									camotime = themap->camo;
								overtime = themap->over;}
							break;
						case SDL_QUIT:
							SDL_Quit();
							Mix_CloseAudio();
							TTF_CloseFont(font);
							exit(0);
					}

					SDL_Delay(20);					   //Delay added to reduce cpu usage
				}
					
				

        }
		return(1);

}



void showTime(const char *str, int weapon_id)
{
	int x,y,w,h;

	switch (weapon_id)
	{
		case SNIPER:
			x = 188;
			y = 153;
			w = 208;
			h = 37;
			break;
		case ROCKETS:
			x = 188;
			y = 203;
			w = 208;
			h = 37;
			break;
		case CAMO:
			x = 332;
			y = 170;
			w = 208;
			h = 37;
			break;
		case OVER:
			x = 332;
			y = 233;
			w = 208;
			h = 37;
			break;
		case HILL:
			x = 188;
			y = 259;
			w = 208;
			h = 37;
			break;
		case GAME:
			x = 389;
			y = 369;
			w = 208;
			h = 71;
			break;
	}
			

	SDL_Color clrFg = {255,255,255,0};
	SDL_Surface *temp = TTF_RenderText_Blended( font, str , clrFg );
	SDL_Rect rcDest = {x,y,w,h};
	SDL_BlitSurface( temp, NULL,  screen, &rcDest );
	SDL_FreeSurface( temp );
}

int setBG(const char *ch)
{
	SDL_Surface *image;
	bg = IMG_Load(ch);
	if(!bg) {
		fprintf(stderr, "IMG_Load: %s\n", IMG_GetError()); return 0;}
	image = SDL_DisplayFormat(bg);
	
	SDL_Rect src;
 
	src.x = 0;
	src.y = 0;
	src.w = image->w;
	src.h = image->h;
 
	bgdest.x = 0;
	bgdest.y = 0;
	bgdest.w = image->w;
	bgdest.h = image->h;
 
	SDL_BlitSurface(image, &src, screen, &bgdest);
	SDL_Flip(screen);
	SDL_FreeSurface(image);


	return 1;
}

int playSound(void *data)
{
	Mix_Chunk *sound = (Mix_Chunk *)data;
	int channel;
	while(Mix_Playing(1) != 0);  //Make sure the mixer isn't already playing audio
	channel = Mix_PlayChannel(1, sound, 0);
	if(channel == -1) {
		fprintf(stderr, "Unable to play WAV file: %s\n", Mix_GetError());
		return -1;
	}
	return 1;
}

void formatTime(char *ch, int tim)
{
	int first, second;
	first = tim/60;
	second = tim % 60;
	*ch = '\0';
	
	char fir[50], sec[50];
	sprintf(fir, "%d", first);
	if (second < 10)
		sprintf(sec, "0%d", second);
	else
		sprintf(sec, "%d", second);
	
	sprintf(ch, "%s:%s", fir, sec);
}

char * addpath(const char *ch)
{
	strcpy(fullpath, PATH);
	strcat(fullpath, ch);
	return fullpath;
}

void redrawScreen()
{
	SDL_FillRect(screen, NULL, 0 ); //Clear the screen of the other timers
	SDL_BlitSurface( bg, NULL, screen, &bgdest);	//Redraw the background
	if (updateNotification())
		SDL_BlitSurface( notification_bg, NULL, screen, &ndest);
}

int displayNotification(char *str, int sec)
{	
	SDL_Color clrFg = {255,255,255,0};
	notification_bg = TTF_RenderText_Blended( font, str , clrFg );
	ndest.x = 30;
	ndest.y = 30;
	ndest.w = 200;
	ndest.h = 100;
	SDL_BlitSurface( notification_bg, NULL,  screen, &ndest );
	
	setNotification(sec);
	
	return 1;
}

int leftsidekeyboard(int key)
{
	switch(key)
	{
		case SDLK_a:
		case SDLK_s:
		case SDLK_d:
		case SDLK_f:
		case SDLK_g:
		case SDLK_q:
		case SDLK_w:
		case SDLK_e:
		case SDLK_r:
		case SDLK_t:
		case SDLK_z:
		case SDLK_x:
		case SDLK_c:
		case SDLK_v:
		case SDLK_b:
		case SDLK_1:
		case SDLK_2:
		case SDLK_3:
		case SDLK_4:
		case SDLK_5:
		case SDLK_SPACE:
		case SDLK_F1:
		case SDLK_F2:
		case SDLK_F3:
		case SDLK_F4:
		case SDLK_F5:
		case SDLK_F6:
		case SDLK_CAPSLOCK:
		case SDLK_LSHIFT:
		case SDLK_TAB:
		case SDLK_LCTRL:
		case SDLK_LALT:
		case SDLK_LSUPER:
			return 1;
		default:
			return 0;
	}
		
}

void displayTimers()
{
	char timer[50];
	formatTime(timer, l_time);
	showTime(timer, GAME);
	
	snipertime = updateSniper(loadmap, snipertime);
	formatTime(timer, snipertime);
	showTime(timer, SNIPER);
	
	rocketstime = updateRockets(loadmap, rocketstime);
	formatTime(timer, rocketstime);
	showTime(timer, ROCKETS);
	
	camotime = updateCamo(loadmap, camotime);
	formatTime(timer, camotime);
	showTime(timer, CAMO);
	
	overtime = updateOver(loadmap, overtime);
	formatTime(timer, overtime);
	showTime(timer, OVER);
	
	hilltime = updateHill(loadmap, hilltime);
	formatTime(timer, hilltime);
	showTime(timer, HILL);
	
	SDL_Flip(screen);
}
